package cn.ulyer.core.modules.system.service.impl;

import cn.ulyer.common.constants.StatusEnum;
import cn.ulyer.common.jpa.entity.Permission;
import cn.ulyer.common.jpa.entity.QPermission;
import cn.ulyer.common.jpa.entity.QRolePermission;
import cn.ulyer.common.jpa.entity.Role;
import cn.ulyer.common.jpa.service.AbstractService;
import cn.ulyer.core.modules.system.service.PermissionService;
import cn.ulyer.core.modules.system.vo.PermissionVo;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PermissionServiceImpl extends AbstractService<Permission, Integer> implements PermissionService {

    @Override
    public List<PermissionVo> allPermissionVo(Predicate ...expression) {
        QPermission qMenu = QPermission.permission;
        JPAQuery<PermissionVo> jpaQuery = jpaQueryFactory.query().select(Projections.bean(PermissionVo.class,
                qMenu.id, qMenu.icon, qMenu.status, qMenu.name, qMenu.priority, qMenu.component, qMenu.url
                , qMenu.createTime, qMenu.updateTime, qMenu.authStrategy
                , qMenu.permissionType, qMenu.permValue, qMenu.parentId)).from(qMenu);
        if(expression!=null){
            jpaQuery.where(expression);
        }
        jpaQuery.orderBy(qMenu.priority.asc(),qMenu.createTime.desc());
        return jpaQuery.fetch();
    }

    @Override
    @Transactional(rollbackOn = Throwable.class)
    public long setDisable(Integer id) {
        QPermission qMenu = QPermission.permission;
        return jpaQueryFactory.update(qMenu).set(qMenu.status, StatusEnum.DISABLED.status())
                .where(qMenu.id.eq(id)).execute();
    }

    @Override
    public List<PermissionVo> PermissionVoByRoles(List<Role> roles, Permission.PermissionType menu) {
        if(CollectionUtils.isEmpty(roles)){
            return new LinkedList<>();
        }
        QPermission qPermission = QPermission.permission;
        QRolePermission rolePermission = QRolePermission.rolePermission;
        List<PermissionVo> vos = jpaQueryFactory.select(
                Projections.bean(PermissionVo.class,
                        qPermission.id, qPermission.parentId, qPermission.permValue, qPermission.component, qPermission.url,
                        qPermission.name, qPermission.priority, qPermission.icon, qPermission.createTime, qPermission.authStrategy
                ))
                .from(qPermission)
                .where(qPermission.id.in(
                        JPAExpressions.select(rolePermission.permissionId).from(rolePermission)
                        .where(rolePermission.roleId.in(roles.stream().map(r->r.getId()).collect(Collectors.toList()))))
                ,qPermission.permissionType.eq(menu)
                ,qPermission.status.eq(StatusEnum.ENABLE.status()))
                .orderBy(qPermission.priority.asc()).fetch();
        return vos;
    }


}
